/*
 * Copyright (C) 2010,2011  Paulo Cesar Pereira de Andrade.
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Authors:
 *	Paulo Cesar Pereira de Andrade
 */

#include "etypes.h"

#ifndef _emath_h
#define _emath_h

#define eadd_over_p(u, v, w)		((w) >= 0 ? (u) < (v) : (u) > (v))
#define esub_over_p(u, v, w)		((w) >= 0 ? (u) > (v) : (u) < (v))

#define thr_qq				&thread_self->qq
#define thr_qr				cqq_realref(&thread_self->qq)
#define thr_qi				cqq_imagref(&thread_self->qq)
#define thr_zr				mpq_numref(thr_qr)
#define thr_z0				mpq_numref(&thread_self->q0)
#define thr_q0				&thread_self->q0
#define thr_f0				&thread_self->f0
#define thr_c				&thread_self->c
#define thr_rr				mpc_realref(&thread_self->c)
#define thr_ri				mpc_imagref(&thread_self->c)
#define thr_rr0				mpc_realref(&thread_self->c0)
#define thr_ri0				mpc_imagref(&thread_self->c0)
#define thr_c0				&thread_self->c0
#define thr_q1				&thread_self->q1
#define thr_q2				&thread_self->q2
#define thr_q3				&thread_self->q3
#define thr_prc				thread_self->prc
#define thr_rnd				thread_self->rnd
#define thr_rndc			RNDC(thr_rnd, thr_rnd)

#define empz_set(z, a)			mpz_set(z, a)
#define empq_set(q, a)			mpq_set(q, a)
#define empr_set(r, a)			mpfr_set(r, a, thr_rnd)
#define ecqq_set(qq, a)			cqq_set(qq, a)
#define empc_set(cc, a)			mpc_set(cc, a, thr_rndc)

#define ecdd_get_i(dd)			real(dd)
#define ecdd_get_d(dd)			real(dd)
#define ecqq_get_i(qq)			empq_get_i(cqq_realref(qq))
#define empc_get_i(rr)			empr_get_i(mpc_realref(rr))
#define empz_get_d(z)			mpz_get_d(z)
#define empq_get_d(q)			mpq_get_d(q)
#define empr_get_d(r)			mpfr_get_d(r, thr_rnd)
#define ecqq_get_d(qq)			mpq_get_d(cqq_realref(qq))
#define empc_get_d(rr)			mpfr_get_d(mpc_realref(rr), thr_rnd)

/*
 * Prototypes
 */
#if !HAVE_C99_CPROJ
#  define cproj(dd)		c99cproj(dd)
extern complex double
c99cproj(complex double dd);
#endif

#if !HAVE_CLOG2
extern complex double
clog2(complex double dd);
#endif

#if !HAVE_CLOG10
extern complex double
clog10(complex double dd);
#endif

extern eint_t
empz_get_i(empz_t z);

#if __WORDSIZE == 32
#  define emp_ui_p(u)			(!((u) & 0xffffffff80000000LL))
#  define emp_si_p(u)			((u) == (eint32_t)(u))

extern eint32_t
empz_fit_i(empz_t z);

extern eint32_t
empz_fit_u(empz_t z);

extern eint32_t
empz_cmp_i(empz_t z, eint_t i);

extern eint32_t
empz_cmp_u(empz_t z, euint_t u);

extern void
empz_set_i(empz_t z, eint_t i);

extern void
empz_set_ii(empz_t z, eint32_t l, eint32_t h);

extern void
empz_set_u(empz_t z, euint_t u);

extern void
empz_set_uu(empz_t z, euint32_t l, euint32_t h);

extern eint32_t
empq_cmp_i(empq_t z, eint_t i);

extern void
empq_set_i(empq_t z, eint_t i);

extern void
empq_set_i_i(empq_t z, eint_t n, eint_t d);

extern eint32_t
empr_cmp_i(empr_t r, eint_t i);

extern void
empr_set_i(empr_t r, eint_t i);

extern void
empc_set_i(empc_t c, eint_t i);

extern void
empc_set_i_i(empc_t c, eint_t r, eint_t i);
#else
#  define emp_ui_p(u)			((u) >= 0)
#  define emp_si_p(u)			1
#  define empz_fit_i(z)			mpz_fits_slong_p(z)
#  define empz_fit_u(z)			mpz_fits_ulong_p(z)
#  define empz_cmp_i(z, i)		mpz_cmp_si(z, i)
#  define empz_cmp_u(z, u)		mpz_cmp_ui(z, u)
#  define empz_set_i(z, i)		mpz_set_si(z, i)
#  define empz_set_u(z, u)		mpz_set_ui(z, u)
#  define empq_cmp_i(z, i)		mpq_cmp_si(z, i, 1)
#  define empq_set_i(q, i)		mpq_set_si(q, i, 1)
#  define empq_set_i_i(q, n, d)		mpq_set_si(q, n, d)
#  define empr_cmp_i(r, i)		mpfr_cmp_si(r, i)
#  define empr_set_i(r, i)		mpfr_set_si(r, i, thr_rnd)
#  define empc_set_i(c, i)		mpc_set_si(c, i, thr_rndc)
#  define empc_set_i_i(c, r, i)		mpc_set_si_si(c, i, thr_rndc)
#endif

extern void
empz_set_r(empz_t z, empr_t r);

/* gmp fails to generate an exception on integer divide by zero
 * and just calls abort... */
#if defined(__ppc__)
extern void
empq_div(empq_t q, empq_t a, empq_t b);

extern void
empq_inv(empq_t q, empq_t a);
#else
#  define empq_canonicalize(q)		mpq_canonicalize(q)
#  define empq_div(q, a, b)		mpq_div(q, a, b)
#  define empq_inv(q, a)		mpq_inv(q, a)
#endif

extern eint_t
empq_get_i(empq_t q);

extern eint_t
empr_get_i(empr_t r);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_com(empz_t z, empz_t a);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_and_i_z(empz_t z, eint_t a, empz_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_and_z_i(empz_t z, empz_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_and_z_z(empz_t z, empz_t a, empz_t b);

extern void
ez_or_i_z(empz_t z, eint_t a, empz_t b);

extern void
ez_or_z_i(empz_t z, empz_t a, eint_t b);

#define ez_or_z_z(z, a, b)		mpz_ior(z, a, b)

/* returns non zero if result fits in an integer */
extern eint32_t
ez_xor_i_z(empz_t z, eint_t a, empz_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_xor_z_i(empz_t z, empz_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_xor_z_z(empz_t z, empz_t a, empz_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_mul2_i_i(empz_t z, eint_t a, eint32_t b);

#define ef_mul2_d_i(a, b)		ldexp(a, b)

#define ez_mul2_z_i(z, a, b)		mpz_mul_2exp(z, a, b)

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_mul2_q_i(empq_t q, empq_t a, eint32_t b);

#define er_mul2_r_i(r, a, b)		mpfr_mul_2exp(r, a, b, thr_rnd)

extern ecdd_t
edd_mul2_dd_i(ecdd_t a, eint32_t b);

#define eqq_mul2_qq_i(qq, a, b)		cqq_mul_2exp(qq, a, b)

#define ecc_mul2_cc_i(cc, a, b)		mpc_mul_2exp(cc, a, b, thr_rndc)

/* returns MININT if result is not exact (or already MININT)
 * if a == MININT and b == 0, the condition should be checked */
extern eint_t
eq_div2_i_i(empq_t q, eint_t a, eint32_t b);

#define ef_div2_d_i(a, b)		ldexp(a, -b)

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_div2_z_i(empq_t q, empz_t a, eint32_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_div2_q_i(empq_t q, empq_t a, eint32_t b);

#define er_div2_r_i(r, a, b)		mpfr_div_2exp(r, a, b, thr_rnd)

extern ecdd_t
edd_div2_dd_i(ecdd_t a, eint32_t b);

#define eqq_div2_qq_i(qq, a, b)		cqq_div_2exp(qq, a, b)

#define ecc_div2_cc_i(cc, a, b)		mpc_div_2exp(cc, a, b, thr_rndc)

#define ez_shl_i_i(z, a, b)		ez_mul2_i_i(z, a, b)

/* returns non zero if result fits in an integer */
extern eint32_t
ez_shl_d_i(empz_t z, efloat_t a, eint32_t b);

#define ez_shl_z_i(z, a, b)		mpz_mul_2exp(z, a, b)

/* returns non zero if result fits in an integer */
extern eint32_t
ez_shl_q_i(empz_t z, empq_t a, eint32_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_shl_r_i(empz_t z, empr_t a, eint32_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_shr_d_i(empz_t z, efloat_t a, eint32_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_shr_z_i(empz_t z, empz_t a, eint32_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_shr_q_i(empz_t z, empq_t a, eint32_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_shr_r_i(empz_t z, empr_t a, eint32_t b);

extern void
ez_add_i_i(empz_t z, eint_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_add_i_z(empz_t z, eint_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_add_i_q(empq_t q, eint_t a, empq_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_add_z_i(empz_t z, empz_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_add_z_z(empz_t z, empz_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_add_z_q(empq_t u, empz_t a, empq_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_add_q_i(empq_t q, empq_t a, eint_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_add_q_z(empq_t q, empq_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_add_q_q(empq_t q, empq_t a, empq_t b);

extern void
er_add_i_r(empr_t r, eint_t a, empr_t b);

extern void
er_add_d_r(empr_t r, efloat_t a, empr_t b);

extern void
er_add_z_r(empr_t r, empz_t a, empr_t b);

extern void
er_add_q_r(empr_t r, empq_t a, empr_t b);

extern void
er_add_r_i(empr_t r, empr_t a, eint_t b);

#define er_add_r_d(r, a, b)		mpfr_add_d(r, a, b, thr_rnd)

extern void
er_add_r_z(empr_t r, empr_t a, empz_t b);

extern void
er_add_r_q(empr_t r, empr_t a, empq_t b);

#define er_add_r_r(r, a, b)		mpfr_add(r, a, b, thr_rnd)

extern ecdd_t
edd_add_d_qq(efloat_t a, ecqq_t b);

extern ecdd_t
edd_add_qq_d(ecqq_t a, efloat_t b);

extern ecdd_t
edd_add_qq_dd(ecqq_t a, ecdd_t b);

extern ecdd_t
edd_add_dd_qq(ecdd_t a, ecqq_t b);

extern void
eqq_add_i_qq(ecqq_t q, eint_t a, ecqq_t b);

extern void
eqq_add_qq_i(ecqq_t q, ecqq_t a, eint_t b);

extern void
eqq_add_qq_z(ecqq_t q, ecqq_t a, empz_t b);

extern void
eqq_add_qq_q(ecqq_t q, ecqq_t a, empq_t b);

extern void
eqq_add_z_qq(ecqq_t q, empz_t a, ecqq_t b);

extern void
eqq_add_q_qq(ecqq_t q, empq_t a, ecqq_t b);

extern void
ecc_add_i_cc(empc_t r, eint_t a, empc_t b);

extern void
ecc_add_d_cc(empc_t r, efloat_t a, empc_t b);

extern void
ecc_add_z_cc(empc_t r, empz_t a, empc_t b);

extern void
ecc_add_q_cc(empc_t r, empq_t a, empc_t b);

extern void
ecc_add_r_dd(empc_t c, empr_t a, ecdd_t b);

extern void
ecc_add_r_qq(empc_t q, empr_t a, ecqq_t b);

extern void
ecc_add_r_cc(empc_t r, empr_t a, empc_t b);

extern void
ecc_add_dd_cc(empc_t c, ecdd_t a, empc_t b);

extern void
ecc_add_dd_r(empc_t c, ecdd_t a, empr_t b);

extern void
ecc_add_qq_r(empc_t c, ecqq_t a, empr_t b);

extern void
ecc_add_qq_cc(empc_t c, ecqq_t a, empc_t b);

extern void
ecc_add_cc_i(empc_t c, empc_t a, eint_t b);

extern void
ecc_add_cc_d(empc_t c, empc_t a, efloat_t b);

extern void
ecc_add_cc_z(empc_t c, empc_t a, empz_t b);

extern void
ecc_add_cc_q(empc_t c, empc_t a, empq_t b);

extern void
ecc_add_cc_r(empc_t c, empc_t a, empr_t b);

extern void
ecc_add_cc_dd(empc_t c, empc_t a, ecdd_t b);

extern void
ecc_add_cc_qq(empc_t c, empc_t a, ecqq_t b);

#define ecc_add_cc_cc(c, a, b)		mpc_add(c, a, b, thr_rndc)

extern void
ez_sub_i_i(empz_t z, eint_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_sub_i_z(empz_t z, eint_t a, empz_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_sub_z_i(empz_t z, empz_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_sub_z_z(empz_t z, empz_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_sub_i_q(empq_t q, eint_t a, empq_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_sub_z_q(empq_t q, empz_t a, empq_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_sub_q_i(empq_t q, empq_t a, eint_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_sub_q_z(empq_t q, empq_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_sub_q_q(empq_t q, empq_t a, empq_t b);

extern void
er_sub_i_r(empr_t r, eint_t a, empr_t b);

#define er_sub_d_r(r, a, b)		mpfr_d_sub(r, a, b, thr_rnd)

extern void
er_sub_z_r(empr_t r, empz_t a, empr_t b);

extern void
er_sub_q_r(empr_t r, empq_t a, empr_t b);

extern void
er_sub_r_i(empr_t r, empr_t a, eint_t b);

#define er_sub_r_d(r, a, b)		mpfr_sub_d(r, a, b, thr_rnd)

extern void
er_sub_r_z(empr_t r, empr_t a, empz_t b);

extern void
er_sub_r_q(empr_t r, empr_t a, empq_t b);

#define er_sub_r_r(r, a, b)		mpfr_sub(r, a, b, thr_rnd)

extern ecdd_t
edd_sub_d_qq(efloat_t a, ecqq_t b);

extern ecdd_t
edd_sub_dd_qq(ecdd_t a, ecqq_t b);

extern ecdd_t
edd_sub_qq_d(ecqq_t a, efloat_t b);

extern ecdd_t
edd_sub_qq_dd(ecqq_t a, ecdd_t b);

extern void
eqq_sub_i_qq(ecqq_t q, eint_t a, ecqq_t b);

extern void
eqq_sub_z_qq(ecqq_t q, empz_t a, ecqq_t b);

extern void
eqq_sub_q_qq(ecqq_t q, empq_t a, ecqq_t b);

extern void
eqq_sub_qq_i(ecqq_t q, ecqq_t a, eint_t b);

extern void
eqq_sub_qq_z(ecqq_t q, ecqq_t a, empz_t b);

extern void
eqq_sub_qq_q(ecqq_t q, ecqq_t a, empq_t b);

extern void
ecc_sub_i_cc(empc_t c, eint_t a, empc_t b);

extern void
ecc_sub_d_cc(empc_t c, efloat_t a, empc_t b);

extern void
ecc_sub_z_cc(empc_t c, empz_t a, empc_t b);

extern void
ecc_sub_q_cc(empc_t c, empq_t a, empc_t b);

extern void
ecc_sub_r_dd(empc_t c, empr_t a, ecdd_t b);

extern void
ecc_sub_r_qq(empc_t q, empr_t a, ecqq_t b);

extern void
ecc_sub_r_cc(empc_t c, empr_t a, empc_t b);

extern void
ecc_sub_dd_r(empc_t c, ecdd_t a, empr_t b);

extern void
ecc_sub_dd_cc(empc_t c, ecdd_t a, empc_t b);

extern void
ecc_sub_qq_r(empc_t c, ecqq_t a, empr_t b);

extern void
ecc_sub_qq_cc(empc_t c, ecqq_t a, empc_t b);

extern void
ecc_sub_cc_i(empc_t c, empc_t a, eint_t b);

extern void
ecc_sub_cc_d(empc_t c, empc_t a, efloat_t b);

extern void
ecc_sub_cc_z(empc_t c, empc_t a, empz_t b);

extern void
ecc_sub_cc_q(empc_t c, empc_t a, empq_t b);

extern void
ecc_sub_cc_r(empc_t c, empc_t a, empr_t b);

extern void
ecc_sub_cc_dd(empc_t c, empc_t a, ecdd_t b);

extern void
ecc_sub_cc_qq(empc_t c, empc_t a, ecqq_t b);

#define ecc_sub_cc_cc(c, a, b)		mpc_sub(c, a, b, thr_rndc)

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ei_mul_i_i(eint_t a, eint_t b);

extern void
ez_mul_i_i(empz_t z, eint_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_mul_i_z(empz_t z, eint_t a, empz_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_mul_z_i(empz_t z, empz_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_mul_z_z(empz_t z, empz_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_mul_i_q(empq_t q, eint_t a, empq_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_mul_z_q(empq_t q, empz_t a, empq_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_mul_q_i(empq_t q, empq_t a, eint_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_mul_q_z(empq_t q, empq_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_mul_q_q(empq_t q, empq_t a, empq_t b);

extern void
er_mul_i_r(empr_t r, eint_t a, empr_t b);

extern void
er_mul_d_r(empr_t r, efloat_t a, empr_t b);

extern void
er_mul_z_r(empr_t r, empz_t a, empr_t b);

extern void
er_mul_q_r(empr_t r, empq_t a, empr_t b);

extern void
er_mul_r_i(empr_t r, empr_t a, eint_t b);

#define er_mul_r_d(r, a, b)		mpfr_mul_d(r, a, b, thr_rnd)

extern void
er_mul_r_z(empr_t r, empr_t a, empz_t b);

extern void
er_mul_r_q(empr_t r, empr_t a, empq_t b);

#define er_mul_r_r(r, a, b)		mpfr_mul(r, a, b, thr_rnd)

extern ecdd_t
edd_mul_d_qq(efloat_t a, ecqq_t b);

extern ecdd_t
edd_mul_dd_qq(ecdd_t a, ecqq_t b);

extern ecdd_t
edd_mul_qq_d(ecqq_t a, efloat_t b);

extern ecdd_t
edd_mul_qq_dd(ecqq_t a, ecdd_t b);

extern void
eqq_mul_i_qq(ecqq_t q, eint_t a, ecqq_t b);

extern void
eqq_mul_z_qq(ecqq_t q, empz_t a, ecqq_t b);

extern void
eqq_mul_q_qq(ecqq_t q, empq_t a, ecqq_t b);

extern void
eqq_mul_qq_i(ecqq_t q, ecqq_t a, eint_t b);

extern void
eqq_mul_qq_z(ecqq_t q, ecqq_t a, empz_t b);

extern void
eqq_mul_qq_q(ecqq_t q, ecqq_t a, empq_t b);

extern void
eqq_mul_qq_qq(ecqq_t q, ecqq_t a, ecqq_t b);

extern void
ecc_mul_i_cc(empc_t q, eint_t a, empc_t b);

extern void
ecc_mul_d_cc(empc_t q, efloat_t a, empc_t b);

extern void
ecc_mul_z_cc(empc_t q, empz_t a, empc_t b);

extern void
ecc_mul_q_cc(empc_t q, empq_t a, empc_t b);

extern void
ecc_mul_r_dd(empc_t c, empr_t a, ecdd_t b);

extern void
ecc_mul_r_cc(empc_t q, empr_t a, empc_t b);

extern void
ecc_mul_r_qq(empc_t c, empr_t a, ecqq_t b);

extern void
ecc_mul_dd_r(empc_t c, ecdd_t a, empr_t b);

extern void
ecc_mul_dd_cc(empc_t q, ecdd_t a, empc_t b);

extern void
ecc_mul_qq_r(empc_t c, ecqq_t a, empr_t b);

extern void
ecc_mul_qq_cc(empc_t q, ecqq_t a, empc_t b);

extern void
ecc_mul_cc_i(empc_t q, empc_t a, eint_t b);

extern void
ecc_mul_cc_d(empc_t q, empc_t a, efloat_t b);

extern void
ecc_mul_cc_z(empc_t q, empc_t a, empz_t b);

extern void
ecc_mul_cc_q(empc_t q, empc_t a, empq_t b);

extern void
ecc_mul_cc_r(empc_t q, empc_t a, empr_t b);

extern void
ecc_mul_cc_dd(empc_t q, empc_t a, ecdd_t b);

extern void
ecc_mul_cc_qq(empc_t q, empc_t a, ecqq_t b);

#define ecc_mul_cc_cc(c, a, b)		mpc_mul(c, a, b, thr_rndc)

extern void
eq_div_i_i(empq_t q, eint_t a, eint_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_div_i_z(empq_t q, eint_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_div_i_q(empq_t q, eint_t a, empq_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
eint32_t
eq_div_z_i(empq_t q, empz_t a, eint_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
eint32_t
eq_div_z_z(empq_t q, empz_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_div_z_q(empq_t q, empz_t a, empq_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_div_q_i(empq_t q, empq_t a, eint_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_div_q_z(empq_t q, empq_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_div_q_q(empq_t q, empq_t a, empq_t b);

extern void
er_div_i_r(empr_t r, eint_t a, empr_t b);

extern void
er_div_d_r(empr_t r, efloat_t a, empr_t b);

extern void
er_div_z_r(empr_t r, empz_t a, empr_t b);

extern void
er_div_q_r(empr_t r, empq_t a, empr_t b);

extern void
er_div_r_i(empr_t r, empr_t a, eint_t b);

extern void
er_div_r_d(empr_t r, empr_t a, efloat_t b);

extern void
er_div_r_z(empr_t r, empr_t a, empz_t b);

extern void
er_div_r_q(empr_t r, empr_t a, empq_t b);

#define er_div_r_r(r, a, b)		mpfr_div(r, a, b, thr_rnd)

extern ecdd_t
edd_div_d_qq(efloat_t a, ecqq_t b);

extern ecdd_t
edd_div_dd_qq(ecdd_t a, ecqq_t b);

extern ecdd_t
edd_div_qq_d(ecqq_t a, efloat_t b);

extern ecdd_t
edd_div_qq_dd(ecqq_t a, ecdd_t b);

extern void
eqq_div_i_qq(ecqq_t q, eint_t a, ecqq_t b);

extern void
eqq_div_z_qq(ecqq_t q, empz_t a, ecqq_t b);

extern void
eqq_div_q_qq(ecqq_t q, empq_t a, ecqq_t b);

extern void
eqq_div_qq_i(ecqq_t q, ecqq_t a, eint_t b);

extern void
eqq_div_qq_z(ecqq_t q, ecqq_t a, empz_t b);

extern void
eqq_div_qq_q(ecqq_t q, ecqq_t a, empq_t b);

extern void
eqq_div_qq_qq(ecqq_t q, ecqq_t a, ecqq_t b);

extern void
ecc_div_i_cc(empc_t c, eint_t a, empc_t b);

extern void
ecc_div_d_cc(empc_t c, efloat_t a, empc_t b);

extern void
ecc_div_z_cc(empc_t c, empz_t a, empc_t b);

extern void
ecc_div_q_cc(empc_t c, empq_t a, empc_t b);

extern void
ecc_div_r_dd(empc_t c, empr_t a, ecdd_t b);

extern void
ecc_div_r_qq(empc_t q, empr_t a, ecqq_t b);

extern void
ecc_div_r_cc(empc_t c, empr_t a, empc_t b);

extern void
ecc_div_dd_cc(empc_t c, ecdd_t a, empc_t b);

extern void
ecc_div_qq_cc(empc_t c, ecqq_t a, empc_t b);

extern void
ecc_div_dd_r(empc_t c, ecdd_t a, empr_t b);

extern void
ecc_div_qq_r(empc_t c, ecqq_t a, empr_t b);

extern void
ecc_div_cc_i(empc_t c, empc_t a, eint_t b);

extern void
ecc_div_cc_d(empc_t c, empc_t a, efloat_t b);

extern void
ecc_div_cc_z(empc_t c, empc_t a, empz_t b);

extern void
ecc_div_cc_q(empc_t c, empc_t a, empq_t b);

extern void
ecc_div_cc_r(empc_t c, empc_t a, empr_t b);

extern void
ecc_div_cc_dd(empc_t c, empc_t a, ecdd_t b);

extern void
ecc_div_cc_qq(empc_t c, empc_t a, ecqq_t b);

#define ecc_div_cc_cc(c, a, b)		mpc_div(c, a, b, thr_rndc)

/* returns non zero if result fits in an integer */
extern eint32_t
ez_trunc_i_z(empz_t z, eint_t a, empz_t b);

/* returns MININT if overflow (or result is already MININT)
 * assumes: z is not mpq_{num,den}ref() of b */
extern eint_t
ez_trunc_i_q(empz_t z, eint_t a, empq_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_i_r(empz_t z, eint_t a, empr_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_d(empz_t z, efloat_t a);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_d_r(empz_t z, efloat_t a, empr_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_z_i(empz_t z, empz_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_trunc_z_z(empz_t z, empz_t a, empz_t b);

/* returns MININT if overflow (or result is already MININT)
 * assumes: z is not mpq_{num,den}ref() of b */
extern eint_t
ez_trunc_z_q(empz_t z, empz_t a, empq_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_z_r(empz_t z, empz_t a, empr_t b);

/* returns MININT if overflow (or result is already MININT)
 * assumes: z is not mpq_{num,den}ref() of a */
extern eint_t
ez_trunc_q_i(empz_t z, empq_t a, eint_t b);

/* returns non zero if result fits in an integer
 * assumes: z is not mpq_{num,den}ref() of a */
extern eint32_t
ez_trunc_q_z(empz_t z, empq_t a, empz_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_q_q(empz_t z, empq_t a, empq_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_q_r(empz_t z, empq_t a, empr_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_r_i(empz_t z, empr_t a, eint_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_r_d(empz_t z, empr_t a, efloat_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_trunc_r_z(empz_t z, empr_t a, empz_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_r_q(empz_t z, empr_t a, empq_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_trunc_r_r(empz_t z, empr_t a, empr_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_rem_i_z(empz_t z, eint_t a, empz_t b);

/* returns MININT if overflow (or result is already MININT) */
extern eint_t
ez_rem_z_i(empz_t z, empz_t a, eint_t b);

/* returns non zero if result fits in an integer */
extern eint32_t
ez_rem_z_z(empz_t z, empz_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_rem_i_q(empq_t q, eint_t a, empq_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_rem_z_q(empq_t q, empz_t v, empq_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_rem_q_i(empq_t q, empq_t a, eint_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_rem_q_z(empq_t q, empq_t a, empz_t b);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_rem_q_q(empq_t q, empq_t a, empq_t b);

extern void
er_rem_i_r(empr_t r, eint_t a, empr_t b);

extern void
er_rem_d_r(empr_t r, efloat_t a, empr_t b);

extern void
er_rem_z_r(empr_t r, empz_t a, empr_t b);

extern void
er_rem_q_r(empr_t r, empq_t a, empr_t b);

extern void
er_rem_r_i(empr_t r, empr_t a, eint_t b);

extern void
er_rem_r_d(empr_t r, empr_t a, efloat_t b);

extern void
er_rem_r_z(empr_t r, empr_t a, empz_t b);

extern void
er_rem_r_q(empr_t r, empr_t a, empq_t b);

#define ed_atan2_i_i(a, b)		atan2(a, b)

#define ed_atan2_i_d(a, b)		atan2(a, b)

#define ed_atan2_i_z(a, b)		atan2(a, mpz_get_d(b))

#define ed_atan2_i_q(a, b)		atan2(a, mpq_get_d(b))

#define ed_atan2_d_i(a, b)		atan2(a, b)

#define ed_atan2_d_d(a, b)		atan2(a, b)

#define ed_atan2_d_z(a, b)		atan2(a, mpz_get_d(b))

#define ed_atan2_d_q(a, b)		atan2(a, mpq_get_d(b))

#define ed_atan2_z_i(a, b)		atan2(mpz_get_d(a), b)

#define ed_atan2_z_d(a, b)		atan2(mpz_get_d(a), b)

#define ed_atan2_z_z(a, b)		atan2(mpz_get_d(a), mpz_get_d(b))

#define ed_atan2_z_q(a, b)		atan2(mpz_get_d(a), mpq_get_d(b))

#define ed_atan2_q_i(a, b)		atan2(mpq_get_d(a), b)

#define ed_atan2_q_d(a, b)		atan2(mpq_get_d(a), b)

#define ed_atan2_q_z(a, b)		atan2(mpq_get_d(a), mpz_get_d(b))

#define ed_atan2_q_q(a, b)		atan2(mpq_get_d(a), mpq_get_d(b))

#define er_rem_r_r(r, a, b)		mpfr_fmod(r, a, b, thr_rnd)

extern void
er_atan2_i_i(empr_t r, eint_t a, eint_t b);

extern void
er_atan2_i_z(empr_t r, eint_t a, empz_t b);

extern void
er_atan2_i_q(empr_t r, eint_t a, empq_t b);

extern void
er_atan2_i_r(empr_t r, eint_t a, empr_t b);

extern void
er_atan2_d_r(empr_t r, efloat_t a, empr_t b);

extern void
er_atan2_z_i(empr_t r, empz_t a, eint_t b);

extern void
er_atan2_z_z(empr_t r, empz_t a, empz_t b);

extern void
er_atan2_z_q(empr_t r, empz_t a, empq_t b);

extern void
er_atan2_z_r(empr_t r, empz_t a, empr_t b);

extern void
er_atan2_q_i(empr_t r, empq_t a, eint_t b);

extern void
er_atan2_q_z(empr_t r, empq_t a, empz_t b);

extern void
er_atan2_q_q(empr_t r, empq_t a, empq_t b);

extern void
er_atan2_q_r(empr_t r, empq_t a, empr_t b);

extern void
er_atan2_r_i(empr_t r, empr_t a, eint_t b);

extern void
er_atan2_r_d(empr_t r, empr_t a, efloat_t b);

extern void
er_atan2_r_z(empr_t r, empr_t a, empz_t b);

extern void
er_atan2_r_q(empr_t r, empr_t a, empq_t b);

#define er_atan2_r_r(r, a, b)		mpfr_atan2(r, a, b, thr_rnd)

extern ecdd_t
edd_atan2_i_dd(eint_t a, ecdd_t b);

extern ecdd_t
edd_atan2_d_dd(efloat_t a, ecdd_t b);

extern ecdd_t
edd_atan2_z_dd(empz_t a, ecdd_t b);

extern ecdd_t
edd_atan2_q_dd(empq_t a, ecdd_t b);

extern ecdd_t
edd_atan2_i_qq(eint_t a, ecqq_t b);

extern ecdd_t
edd_atan2_d_qq(efloat_t a, ecqq_t b);

extern ecdd_t
edd_atan2_z_qq(empz_t a, ecqq_t b);

extern ecdd_t
edd_atan2_q_qq(empq_t a, ecqq_t b);

extern ecdd_t
edd_atan2_dd_i(ecdd_t a, eint_t b);

extern ecdd_t
edd_atan2_dd_d(ecdd_t a, efloat_t b);

extern ecdd_t
edd_atan2_dd_z(ecdd_t a, empz_t b);

extern ecdd_t
edd_atan2_dd_q(ecdd_t a, empq_t b);

#define edd_atan2_dd_dd(a, b)		catan(a / b)

extern ecdd_t
edd_atan2_dd_qq(ecdd_t a, ecqq_t b);

extern ecdd_t
edd_atan2_qq_i(ecqq_t a, eint_t b);

extern ecdd_t
edd_atan2_qq_d(ecqq_t a, efloat_t b);

extern ecdd_t
edd_atan2_qq_z(ecqq_t a, empz_t b);

extern ecdd_t
edd_atan2_qq_q(ecqq_t a, empq_t b);

extern ecdd_t
edd_atan2_qq_dd(ecqq_t a, ecdd_t b);

extern ecdd_t
edd_atan2_qq_qq(ecqq_t a, ecqq_t b);

extern void
ecc_atan2_i_qq(empc_t r, eint_t a, ecqq_t b);

extern void
ecc_atan2_i_cc(empc_t c, eint_t a, empc_t b);

extern void
ecc_atan2_d_cc(empc_t c, efloat_t a, empc_t b);

extern void
ecc_atan2_z_qq(empc_t c, empz_t a, ecqq_t b);

extern void
ecc_atan2_z_cc(empc_t c, empz_t a, empc_t b);

extern void
ecc_atan2_q_cc(empc_t c, empq_t a, empc_t b);

extern void
ecc_atan2_cc_i(empc_t c, empc_t a, eint_t b);

extern void
ecc_atan2_cc_d(empc_t c, empc_t a, efloat_t b);

extern void
ecc_atan2_cc_z(empc_t c, empc_t a, empz_t b);

extern void
ecc_atan2_cc_q(empc_t c, empc_t a, empq_t b);

extern void
ecc_atan2_q_qq(empc_t c, empq_t a, ecqq_t b);

extern void
ecc_atan2_r_dd(empc_t c, empr_t a, ecdd_t b);

extern void
ecc_atan2_r_qq(empc_t c, empr_t a, ecqq_t b);

extern void
ecc_atan2_r_cc(empc_t c, empr_t a, empc_t b);

extern void
ecc_atan2_dd_cc(empc_t c, ecdd_t a, empc_t b);

extern void
ecc_atan2_qq_cc(empc_t c, ecqq_t a, empc_t b);

extern void
ecc_atan2_dd_r(empc_t c, ecdd_t a, empr_t b);

extern void
ecc_atan2_qq_i(empc_t c, ecqq_t a, eint_t b);

extern void
ecc_atan2_qq_z(empc_t c, ecqq_t a, empz_t b);

extern void
ecc_atan2_qq_q(empc_t c, ecqq_t a, empq_t b);

extern void
ecc_atan2_qq_r(empc_t c, ecqq_t a, empr_t b);

extern void
ecc_atan2_qq_qq(empc_t c, ecqq_t a, ecqq_t b);

extern void
ecc_atan2_cc_r(empc_t c, empc_t a, empr_t b);

extern void
ecc_atan2_cc_dd(empc_t c, empc_t a, ecdd_t b);

extern void
ecc_atan2_cc_qq(empc_t c, empc_t a, ecqq_t b);

extern void
ecc_atan2_cc_cc(empc_t c, empc_t a, empc_t b);

#define ed_pow_i_i(a, b)		pow(a, b)

#define ed_pow_i_d(a, b)		pow(a, b)

#define ed_pow_i_z(a, b)		pow(a, mpz_get_d(b))

#define ed_pow_i_q(a, b)		pow(a, mpq_get_d(b))

#define ed_pow_d_i(a, b)		pow(a, b)

#define ed_pow_d_d(a, b)		pow(a, b)

#define ed_pow_d_z(a, b)		pow(a, mpz_get_d(b))

#define ed_pow_d_q(a, b)		pow(a, mpq_get_d(b))

#define ed_pow_z_i(a, b)		pow(mpz_get_d(a), b)

#define ed_pow_z_d(a, b)		pow(mpz_get_d(a), b)

#define ed_pow_z_z(a, b)		pow(mpz_get_d(a), mpz_get_d(b))

#define ed_pow_z_q(a, b)		pow(mpz_get_d(a), mpq_get_d(b))

#define ed_pow_q_i(a, b)		pow(mpq_get_d(a), b)

#define ed_pow_q_d(a, b)		pow(mpq_get_d(a), b)

#define ed_pow_q_z(a, b)		pow(mpq_get_d(a), mpz_get_d(b))

#define ed_pow_q_q(a, b)		pow(mpq_get_d(a), mpq_get_d(b))

extern void
er_pow_i_i(empr_t r, eint_t a, eint_t b);

extern void
er_pow_i_z(empr_t r, eint_t a, empz_t b);

extern void
er_pow_i_q(empr_t r, eint_t a, empq_t b);

extern void
er_pow_i_r(empr_t r, eint_t a, empr_t b);

extern void
er_pow_d_r(empr_t r, efloat_t a, empr_t b);

extern void
er_pow_z_i(empr_t r, empz_t a, eint_t b);

extern void
er_pow_z_z(empr_t r, empz_t a, empz_t b);

extern void
er_pow_z_q(empr_t r, empz_t a, empq_t b);

extern void
er_pow_z_r(empr_t r, empz_t a, empr_t b);

extern void
er_pow_q_i(empr_t r, empq_t a, eint_t b);

extern void
er_pow_q_z(empr_t r, empq_t a, empz_t b);

extern void
er_pow_q_q(empr_t r, empq_t a, empq_t b);

extern void
er_pow_q_r(empr_t r, empq_t a, empr_t b);

extern void
er_pow_r_i(empr_t r, empr_t a, eint_t b);

extern void
er_pow_r_d(empr_t r, empr_t a, efloat_t b);

extern void
er_pow_r_z(empr_t r, empr_t a, empz_t b);

extern void
er_pow_r_q(empr_t r, empr_t a, empq_t b);

#define er_pow_r_r(r, a, b)		mpfr_pow(r, a, b, thr_rnd)

extern ecdd_t
edd_pow_i_d(eint_t a, efloat_t b);

extern ecdd_t
edd_pow_i_q(eint_t a, empq_t b);

extern ecdd_t
edd_pow_i_dd(eint_t a, ecdd_t b);

extern ecdd_t
edd_pow_i_qq(eint_t a, ecqq_t b);

extern ecdd_t
edd_pow_d_i(efloat_t a, eint_t b);

extern ecdd_t
edd_pow_d_d(efloat_t a, efloat_t b);

extern ecdd_t
edd_pow_d_q(efloat_t a, empq_t b);

extern ecdd_t
edd_pow_d_dd(efloat_t a, ecdd_t b);

extern ecdd_t
edd_pow_d_qq(efloat_t a, ecqq_t b);

extern ecdd_t
edd_pow_z_d(empz_t a, efloat_t b);

extern ecdd_t
edd_pow_z_q(empz_t a, empq_t b);

extern ecdd_t
edd_pow_z_dd(empz_t a, ecdd_t b);

extern ecdd_t
edd_pow_z_qq(empz_t a, ecqq_t b);

extern ecdd_t
edd_pow_q_d(empq_t a, efloat_t b);

extern ecdd_t
edd_pow_q_q(empq_t a, empq_t b);

extern ecdd_t
edd_pow_q_dd(empq_t a, ecdd_t b);

extern ecdd_t
edd_pow_q_qq(empq_t a, ecqq_t b);

extern ecdd_t
edd_pow_dd_i(ecdd_t a, eint_t b);

extern ecdd_t
edd_pow_dd_d(ecdd_t a, efloat_t b);

extern ecdd_t
edd_pow_dd_z(ecdd_t a, empz_t b);

extern ecdd_t
edd_pow_dd_q(ecdd_t a, empq_t b);

#define edd_pow_dd_dd(a, b)		cpow(a, b)

extern ecdd_t
edd_pow_dd_qq(ecdd_t a, ecqq_t b);

extern ecdd_t
edd_pow_qq_i(ecqq_t a, eint_t b);

extern ecdd_t
edd_pow_qq_d(ecqq_t a, efloat_t b);

extern ecdd_t
edd_pow_qq_z(ecqq_t a, empz_t b);

extern ecdd_t
edd_pow_qq_q(ecqq_t a, empq_t b);

extern ecdd_t
edd_pow_qq_dd(ecqq_t a, ecdd_t b);

extern ecdd_t
edd_pow_qq_qq(ecqq_t a, ecqq_t b);

extern void
ecc_pow_i_q(empc_t c, eint_t a, empq_t b);

extern void
ecc_pow_i_r(empc_t c, eint_t a, empr_t b);

extern void
ecc_pow_i_qq(empc_t c, eint_t a, ecqq_t b);

extern void
ecc_pow_d_r(empc_t c, efloat_t a, empr_t b);

extern void
ecc_pow_i_cc(empc_t c, eint_t a, empc_t b);

extern void
ecc_pow_d_r(empc_t c, efloat_t a, empr_t b);

extern void
ecc_pow_d_cc(empc_t c, efloat_t a, empc_t b);

extern void
ecc_pow_z_q(empc_t c, empz_t a, empq_t b);

extern void
ecc_pow_z_r(empc_t c, empz_t a, empr_t b);

extern void
ecc_pow_z_qq(empc_t c, empz_t a, ecqq_t b);

extern void
ecc_pow_z_cc(empc_t c, empz_t a, empc_t b);

extern void
ecc_pow_q_q(empc_t c, empq_t a, empq_t b);

extern void
ecc_pow_q_r(empc_t c, empq_t a, empr_t b);

extern void
ecc_pow_q_qq(empc_t c, empq_t a, ecqq_t b);

extern void
ecc_pow_q_cc(empc_t c, empq_t a, empc_t b);

extern void
ecc_pow_r_d(empc_t c, empr_t a, efloat_t b);

extern void
ecc_pow_r_q(empc_t c, empr_t a, empq_t b);

extern void
ecc_pow_r_r(empc_t c, empr_t a, empr_t b);

extern void
ecc_pow_r_dd(empc_t c, empr_t a, ecdd_t b);

extern void
ecc_pow_r_qq(empc_t c, empr_t a, ecqq_t b);

extern void
ecc_pow_r_cc(empc_t c, empr_t a, empc_t b);

extern void
ecc_pow_dd_r(empc_t c, ecdd_t a, empr_t b);

extern void
ecc_pow_dd_cc(empc_t c, ecdd_t a, empc_t b);

extern void
ecc_pow_qq_i(empc_t c, ecqq_t a, eint_t b);

extern void
ecc_pow_qq_z(empc_t c, ecqq_t a, empz_t b);

extern void
ecc_pow_qq_q(empc_t c, ecqq_t a, empq_t b);

extern void
ecc_pow_qq_r(empc_t c, ecqq_t a, empr_t b);

extern void
ecc_pow_qq_qq(empc_t c, ecqq_t a, ecqq_t b);

extern void
ecc_pow_qq_cc(empc_t c, ecqq_t a, empc_t b);

extern void
ecc_pow_cc_i(empc_t c, empc_t a, eint_t b);

extern void
ecc_pow_cc_d(empc_t c, empc_t a, efloat_t b);

extern void
ecc_pow_cc_z(empc_t c, empc_t a, empz_t b);

extern void
ecc_pow_cc_q(empc_t c, empc_t a, empq_t b);

#define ecc_pow_cc_r(c, a, b)		mpc_pow_fr(c, a, b, thr_rndc)

extern void
ecc_pow_cc_dd(empc_t c, empc_t a, ecdd_t b);

extern void
ecc_pow_cc_qq(empc_t c, empc_t a, ecqq_t b);

#define ecc_pow_cc_cc(c, a, b)		mpc_pow(c, a, b, thr_rndc)

#define ed_hypot_i_i(a, b)		hypot(a, b)

#define ed_hypot_i_d(a, b)		hypot(a, b)

#define ed_hypot_i_z(a, b)		hypot(a, mpz_get_d(b))

#define ed_hypot_i_q(a, b)		hypot(a, mpq_get_d(b))

extern efloat_t
ed_hypot_i_dd(eint_t a, ecdd_t b);

extern efloat_t
ed_hypot_i_qq(eint_t a, ecqq_t b);

#define ed_hypot_d_i(a, b)		hypot(a, b)

#define ed_hypot_d_d(a, b)		hypot(a, b)

#define ed_hypot_d_z(a, b)		hypot(a, mpz_get_d(b))

#define ed_hypot_d_q(a, b)		hypot(a, mpq_get_d(b))

extern efloat_t
ed_hypot_d_dd(efloat_t a, ecdd_t b);

extern efloat_t
ed_hypot_d_qq(efloat_t a, ecqq_t b);

#define ed_hypot_z_i(a, b)		hypot(mpz_get_d(a), b)

#define ed_hypot_z_d(a, b)		hypot(mpz_get_d(a), b)

#define ed_hypot_z_z(a, b)		hypot(mpz_get_d(a), mpz_get_d(b))

#define ed_hypot_z_q(a, b)		hypot(mpz_get_d(a), mpq_get_d(b))

extern efloat_t
ed_hypot_z_dd(empz_t a, ecdd_t b);

extern efloat_t
ed_hypot_z_qq(empz_t a, ecqq_t b);

#define ed_hypot_q_i(a, b)		hypot(mpq_get_d(a), b)

#define ed_hypot_q_d(a, b)		hypot(mpq_get_d(a), b)

#define ed_hypot_q_z(a, b)		hypot(mpq_get_d(a), mpz_get_d(b))

#define ed_hypot_q_q(a, b)		hypot(mpq_get_d(a), mpq_get_d(b))

extern efloat_t
ed_hypot_q_dd(empq_t a, ecdd_t b);

extern efloat_t
ed_hypot_q_qq(empq_t a, ecqq_t b);

extern efloat_t
ed_hypot_dd_i(ecdd_t a, eint_t b);

extern efloat_t
ed_hypot_dd_d(ecdd_t a, efloat_t b);

extern efloat_t
ed_hypot_dd_z(ecdd_t a, empz_t b);

extern efloat_t
ed_hypot_dd_q(ecdd_t a, empq_t b);

extern efloat_t
ed_hypot_dd_dd(ecdd_t a, ecdd_t b);

extern efloat_t
ed_hypot_dd_qq(ecdd_t a, ecqq_t b);

extern efloat_t
ed_hypot_qq_i(ecqq_t a, eint_t b);

extern efloat_t
ed_hypot_qq_d(ecqq_t a, efloat_t b);

extern efloat_t
ed_hypot_qq_z(ecqq_t a, empz_t b);

extern efloat_t
ed_hypot_qq_q(ecqq_t a, empq_t b);

extern efloat_t
ed_hypot_qq_dd(ecqq_t a, ecdd_t b);

extern efloat_t
ed_hypot_qq_qq(ecqq_t a, ecqq_t b);

extern void
er_hypot_i_i(empr_t r, eint_t a, eint_t b);

extern void
er_hypot_i_z(empr_t r, eint_t a, empz_t b);

extern void
er_hypot_i_q(empr_t r, eint_t a, empq_t b);

extern void
er_hypot_i_r(empr_t r, eint_t a, empr_t b);

extern void
er_hypot_i_qq(empr_t r, eint_t a, ecqq_t b);

extern void
er_hypot_i_cc(empr_t r, eint_t a, empc_t b);

extern void
er_hypot_d_r(empr_t r, efloat_t a, empr_t b);

extern void
er_hypot_d_cc(empr_t r, efloat_t a, empc_t b);

extern void
er_hypot_z_i(empr_t r, empz_t a, eint_t b);

extern void
er_hypot_z_z(empr_t r, empz_t a, empz_t b);

extern void
er_hypot_z_q(empr_t r, empz_t a, empq_t b);

extern void
er_hypot_z_r(empr_t r, empz_t a, empr_t b);

extern void
er_hypot_z_qq(empr_t r, empz_t a, ecqq_t b);

extern void
er_hypot_z_cc(empr_t r, empz_t a, empc_t b);

extern void
er_hypot_q_i(empr_t r, empq_t a, eint_t b);

extern void
er_hypot_q_z(empr_t r, empq_t a, empz_t b);

extern void
er_hypot_q_q(empr_t r, empq_t a, empq_t b);

extern void
er_hypot_q_r(empr_t r, empq_t a, empr_t b);

extern void
er_hypot_q_qq(empr_t r, empq_t a, ecqq_t b);

extern void
er_hypot_q_cc(empr_t r, empq_t a, empc_t b);

extern void
er_hypot_r_i(empr_t r, empr_t a, eint_t b);

extern void
er_hypot_r_d(empr_t r, empr_t a, efloat_t b);

extern void
er_hypot_r_z(empr_t r, empr_t a, empz_t b);

extern void
er_hypot_r_q(empr_t r, empr_t a, empq_t b);

#define er_hypot_r_r(r, a, b)		mpfr_hypot(r, a, b, thr_rnd)

extern void
er_hypot_r_dd(empr_t r, empr_t a, ecdd_t b);

extern void
er_hypot_r_qq(empr_t r, empr_t a, ecqq_t b);

extern void
er_hypot_r_cc(empr_t r, empr_t a, empc_t b);

extern void
er_hypot_dd_r(empr_t r, ecdd_t a, empr_t b);

extern void
er_hypot_dd_cc(empr_t r, ecdd_t a, empc_t b);

extern void
er_hypot_qq_i(empr_t r, ecqq_t a, eint_t b);

extern void
er_hypot_qq_z(empr_t r, ecqq_t a, empz_t b);

extern void
er_hypot_qq_q(empr_t r, ecqq_t a, empq_t b);

extern void
er_hypot_qq_r(empr_t r, ecqq_t a, empr_t b);

extern void
er_hypot_qq_qq(empr_t r, ecqq_t a, ecqq_t b);

extern void
er_hypot_qq_cc(empr_t r, ecqq_t a, empc_t b);

extern void
er_hypot_cc_i(empr_t r, empc_t a, eint_t b);

extern void
er_hypot_cc_d(empr_t r, empc_t a, efloat_t b);

extern void
er_hypot_cc_z(empr_t r, empc_t a, empz_t b);

extern void
er_hypot_cc_q(empr_t r, empc_t a, empq_t b);

extern void
er_hypot_cc_r(empr_t r, empc_t a, empr_t b);

extern void
er_hypot_cc_dd(empr_t r, empc_t a, ecdd_t b);

extern void
er_hypot_cc_qq(empr_t r, empc_t a, ecqq_t b);

extern void
er_hypot_cc_cc(empr_t r, empc_t a, empc_t b);

#define ei_signum_i(a)			(a ? a > 0 ? 1 : -1 : 0)

#define ei_signum_z(a)			mpz_sgn(a)

#define ei_signum_q(a)			mpq_sgn(a)

extern efloat_t
ed_signum_d(efloat_t a);

extern void
er_signum_r(empr_t r, empr_t a);

#define edd_signum_dd(a)		(a / cabs(a))

extern ecdd_t
edd_signum_qq(ecqq_t a);

extern void
ecc_signum_qq(empc_t c, ecqq_t a);

extern void
ecc_signum_cc(empc_t c, empc_t a);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_rational_d(empq_t q, efloat_t a);

/* returns  0 if result is a mpq_t
 * returns -1 if result can be converted to mpz_t (denominator is 1)
 * returns  1 if result fits in an eint_t and denominator is 1 */
extern eint32_t
eq_rational_r(empq_t q, empr_t a);

#define edd_conj_dd(a)			conj(a)

extern void
eqq_conj_qq(ecqq_t qq, ecqq_t a);

extern void
ecc_conj_cc(empc_t c, empc_t a);

#define ed_arg_i(a)			((a) >= 0 ? 0.0 : M_PI)

extern efloat_t
ed_arg_d(efloat_t a);

#define ed_arg_z(a)			(mpz_sgn(a) >= 0 ? 0.0 : M_PI)

#define ed_arg_q(a)			(mpq_sgn(a) >= 0 ? 0.0 : M_PI)

#define ed_arg_dd(a)			carg(a)

extern efloat_t
ed_arg_qq(ecqq_t a);

extern void
er_arg_i(empr_t r, eint_t a);

extern void
er_arg_z(empr_t r, empz_t a);

extern void
er_arg_q(empr_t r, empq_t a);

extern void
er_arg_r(empr_t r, empr_t a);

extern void
er_arg_qq(empr_t r, ecqq_t a);

#define er_arg_cc(r, a)			mpc_arg(r, a, thr_rndc)

#define ed_abs_i(a)			fabs(a)

#define ed_abs_d(a)			fabs(a)

#define ed_abs_z(a)			fabs(mpz_get_d(a))

#define ed_abs_q(a)			fabs(mpq_get_d(a))

/* returns MININT if argument is MININT */
extern eint_t
ez_abs_i(empz_t z, eint_t a);

#define ez_abs_z(z, a)			mpz_abs(z, a)

#define eq_abs_q(q, a)			mpq_abs(q, a)

#define ed_abs_dd(a)			cabs(a)

extern efloat_t
ed_abs_qq(ecqq_t a);

extern efloat_t
ed_abs_qq(ecqq_t a);

extern void
er_abs_i(empr_t r, eint_t a);

extern void
er_abs_z(empr_t r, empz_t a);

extern void
er_abs_q(empr_t r, empq_t a);

#define er_abs_r(r, a)			mpfr_abs(r, a, thr_rnd)

extern void
er_abs_qq(empr_t r, ecqq_t a);

#define er_abs_cc(c, a)			mpc_abs(c, a, thr_rndc)

#define ed_sqrt_i(a)			sqrt(a)

#define ed_sqrt_d(a)			sqrt(a)

#define ed_sqrt_z(a)			sqrt(mpz_get_d(a))

#define ed_sqrt_q(a)			sqrt(mpq_get_d(a))

extern void
er_sqrt_i(empr_t r, eint_t a);

extern void
er_sqrt_z(empr_t c, empz_t a);

extern void
er_sqrt_q(empr_t c, empq_t a);

#define edd_sqrt_dd(a)			csqrt(a)

#define er_sqrt_r(r, a)			mpfr_sqrt(r, a, thr_rnd)

extern ecdd_t
edd_sqrt_i(eint_t a);

extern ecdd_t
edd_sqrt_d(efloat_t a);

extern ecdd_t
edd_sqrt_z(empz_t a);

extern ecdd_t
edd_sqrt_q(empq_t a);

#define edd_sqrt_dd(a)			csqrt(a)

extern ecdd_t
edd_sqrt_qq(ecqq_t a);

extern void
ecc_sqrt_i(empc_t c, eint_t a);

extern void
ecc_sqrt_z(empc_t c, empz_t a);

extern void
ecc_sqrt_q(empc_t c, empq_t a);

extern void
ecc_sqrt_r(empc_t c, empr_t a);

extern void
ecc_sqrt_qq(empc_t c, ecqq_t a);

#define ecc_sqrt_cc(c, a)		mpc_sqrt(c, a, thr_rndc)

#define ed_cbrt_i(a)			cbrt(a)

#define ed_cbrt_d(a)			cbrt(a)

#define ed_cbrt_z(a)			cbrt(mpz_get_d(a))

#define ed_cbrt_q(a)			cbrt(mpq_get_d(a))

extern void
er_cbrt_i(empr_t r, eint_t a);

extern void
er_cbrt_z(empr_t r, empz_t a);

extern void
er_cbrt_q(empr_t r, empq_t a);

#define er_cbrt_r(r, a)			mpfr_cbrt(r, a, thr_rnd)

extern ecdd_t
edd_cbrt_dd(ecdd_t a);

extern ecdd_t
edd_cbrt_qq(ecqq_t a);

extern void
ecc_cbrt_qq(empc_t c, ecqq_t a);

extern void
ecc_cbrt_cc(empc_t c, empc_t a);

#define ed_sin_i(a)			sin(a)

#define ed_sin_d(a)			sin(a)

#define ed_sin_z(a)			sin(mpz_get_d(a))

#define ed_sin_q(a)			sin(mpq_get_d(a))

#define er_sin_r(r, a)			mpfr_sin(r, a, thr_rnd)

extern void
er_sin_i(empr_t r, eint_t a);

extern void
er_sin_z(empr_t r, empz_t a);

extern void
er_sin_q(empr_t r, empq_t a);

#define edd_sin_dd(a)			csin(a)

extern ecdd_t
edd_sin_qq(ecqq_t a);

extern void
ecc_sin_qq(empc_t c, ecqq_t a);

#define ecc_sin_cc(c, a)		mpc_sin(c, a, thr_rndc)

extern void
er_cos_i(empr_t r, eint_t a);

extern void
er_cos_z(empr_t r, empz_t a);

extern void
er_cos_q(empr_t r, empq_t a);

#define ed_cos_i(a)			cos(a)

#define ed_cos_d(a)			cos(a)

#define ed_cos_z(a)			cos(mpz_get_d(a))

#define ed_cos_q(a)			cos(mpq_get_d(a))

#define er_cos_r(r, a)			mpfr_cos(r, a, thr_rnd)

#define edd_cos_dd(a)			ccos(a)

extern ecdd_t
edd_cos_qq(ecqq_t a);

extern void
ecc_cos_qq(empc_t c, ecqq_t a);

#define ecc_cos_cc(c, a)		mpc_cos(c, a, thr_rndc)

extern void
er_tan_i(empr_t r, eint_t a);

extern void
er_tan_z(empr_t r, empz_t a);

extern void
er_tan_q(empr_t r, empq_t a);

#define ed_tan_i(a)			tan(a)

#define ed_tan_d(a)			tan(a)

#define ed_tan_z(a)			tan(mpz_get_d(a))

#define ed_tan_q(a)			tan(mpq_get_d(a))

#define er_tan_r(r, a)			mpfr_tan(r, a, thr_rnd)

#define edd_tan_dd(a)			ctan(a)

extern ecdd_t
edd_tan_qq(ecqq_t a);

extern void
ecc_tan_qq(empc_t c, ecqq_t a);

#define ecc_tan_cc(c, a)		mpc_tan(c, a, thr_rndc)

#define ed_asin_i(a)			asin(a)

#define ed_asin_d(a)			asin(a)

#define ed_asin_z(a)			asin(mpz_get_d(a))

#define ed_asin_q(a)			asin(mpq_get_d(a))

extern void
er_asin_i(empr_t r, eint_t a);

extern void
er_asin_z(empr_t r, empz_t a);

extern void
er_asin_q(empr_t r, empq_t a);

#define er_asin_r(r, a)			mpfr_asin(r, a, thr_rnd)

extern ecdd_t
edd_asin_i(eint_t a);

extern ecdd_t
edd_asin_d(efloat_t a);

extern ecdd_t
edd_asin_z(empz_t a);

extern ecdd_t
edd_asin_q(empq_t a);

#define edd_asin_dd(a)			casin(a)

extern ecdd_t
edd_asin_qq(ecqq_t a);

extern void
ecc_asin_i(empc_t c, eint_t a);

extern void
ecc_asin_z(empc_t c, empz_t a);

extern void
ecc_asin_q(empc_t c, empq_t a);

extern void
ecc_asin_r(empc_t c, empr_t a);

extern void
ecc_asin_qq(empc_t c, ecqq_t a);

#define ecc_asin_cc(c, a)		mpc_asin(c, a, thr_rndc)

#define ed_acos_i(a)			acos(a)

#define ed_acos_d(a)			acos(a)

#define ed_acos_z(a)			acos(mpz_get_d(a))

#define ed_acos_q(a)			acos(mpq_get_d(a))

extern void
er_acos_i(empr_t r, eint_t a);

extern void
er_acos_z(empr_t r, empz_t a);

extern void
er_acos_q(empr_t r, empq_t a);

#define er_acos_r(r, a)			mpfr_acos(r, a, thr_rnd)

extern ecdd_t
edd_acos_i(eint_t a);

extern ecdd_t
edd_acos_d(efloat_t a);

extern ecdd_t
edd_acos_z(empz_t a);

extern ecdd_t
edd_acos_q(empq_t a);

#define edd_acos_dd(a)			cacos(a)

extern ecdd_t
edd_acos_qq(ecqq_t a);

extern void
ecc_acos_i(empc_t c, eint_t a);

extern void
ecc_acos_z(empc_t c, empz_t a);

extern void
ecc_acos_q(empc_t c, empq_t a);

extern void
ecc_acos_r(empc_t c, empr_t a);

extern void
ecc_acos_qq(empc_t c, ecqq_t a);

#define ecc_acos_cc(c, a)		mpc_acos(c, a, thr_rndc)

#define ed_atan_i(a)			atan(a)

#define ed_atan_d(a)			atan(a)

#define ed_atan_z(a)			atan(mpz_get_d(a))

#define ed_atan_q(a)			atan(mpq_get_d(a))

extern void
er_atan_i(empr_t r, eint_t a);

extern void
er_atan_z(empr_t r, empz_t a);

extern void
er_atan_q(empr_t r, empq_t a);

#define er_atan_r(r, a)			mpfr_atan(r, a, thr_rnd)

#define edd_atan_dd(a)			catan(a)

extern ecdd_t
edd_atan_qq(ecqq_t a);

extern void
ecc_atan_qq(empc_t c, ecqq_t a);

#define ecc_atan_cc(c, a)		mpc_atan(c, a, thr_rndc)

#define ed_sinh_i(a)			sinh(a)

#define ed_sinh_d(a)			sinh(a)

#define ed_sinh_z(a)			sinh(mpz_get_d(a))

#define ed_sinh_q(a)			sinh(mpq_get_d(a))

extern void
er_sinh_i(empr_t r, eint_t a);

extern void
er_sinh_z(empr_t r, empz_t a);

extern void
er_sinh_q(empr_t r, empq_t a);

#define er_sinh_r(r, a)			mpfr_sinh(r, a, thr_rnd)

#define edd_sinh_dd(a)			csinh(a)

extern ecdd_t
edd_sinh_qq(ecqq_t a);

extern void
ecc_sinh_qq(empc_t c, ecqq_t a);

#define ecc_sinh_cc(c, a)		mpc_sinh(c, a, thr_rndc)

#define ed_cosh_i(a)			cosh(a)

#define ed_cosh_d(a)			cosh(a)

#define ed_cosh_z(a)			cosh(mpz_get_d(a))

#define ed_cosh_q(a)			cosh(mpq_get_d(a))

extern void
er_cosh_i(empr_t r, eint_t a);

extern void
er_cosh_z(empr_t r, empz_t a);

extern void
er_cosh_q(empr_t r, empq_t a);

#define er_cosh_r(r, a)			mpfr_cosh(r, a, thr_rnd)

#define edd_cosh_dd(a)			ccosh(a)

extern ecdd_t
edd_cosh_qq(ecqq_t a);

extern void
ecc_cosh_qq(empc_t c, ecqq_t a);

#define ecc_cosh_cc(c, a)		mpc_cosh(c, a, thr_rndc)

#define ed_tanh_i(a)			tanh(a)

#define ed_tanh_d(a)			tanh(a)

#define ed_tanh_z(a)			tanh(mpz_get_d(a))

#define ed_tanh_q(a)			tanh(mpq_get_d(a))

extern void
er_tanh_i(empr_t r, eint_t a);

extern void
er_tanh_z(empr_t r, empz_t a);

extern void
er_tanh_q(empr_t r, empq_t a);

#define er_tanh_r(r, a)			mpfr_tanh(r, a, thr_rnd)

#define edd_tanh_dd(a)			ctanh(a)

extern ecdd_t
edd_tanh_qq(ecqq_t a);

extern void
ecc_tanh_qq(empc_t c, ecqq_t a);

#define ecc_tanh_cc(c, a)		mpc_tanh(c, a, thr_rndc)

#define ed_asinh_i(a)			asinh(a)

#define ed_asinh_d(a)			asinh(a)

#define ed_asinh_z(a)			asinh(mpz_get_d(a))

#define ed_asinh_q(a)			asinh(mpq_get_d(a))

extern void
er_asinh_i(empr_t r, eint_t a);

extern void
er_asinh_z(empr_t r, empz_t a);

extern void
er_asinh_q(empr_t r, empq_t a);

#define er_asinh_r(r, a)		mpfr_asinh(r, a, thr_rnd)

#define edd_asinh_dd(a)			casinh(a)

extern ecdd_t
edd_asinh_qq(ecqq_t a);

extern void
ecc_asinh_qq(empc_t c, ecqq_t a);

#define ecc_asinh_cc(c, a)		mpc_asinh(c, a, thr_rndc)

#define ed_acosh_i(a)			acosh(a)

#define ed_acosh_d(a)			acosh(a)

#define ed_acosh_z(a)			acosh(mpz_get_d(a))

#define ed_acosh_q(a)			acosh(mpq_get_d(a))

extern void
er_acosh_i(empr_t r, eint_t a);

extern void
er_acosh_z(empr_t r, empz_t a);

extern void
er_acosh_q(empr_t r, empq_t a);

#define er_acosh_r(r, a)		mpfr_acosh(r, a, thr_rnd)

extern ecdd_t
edd_acosh_i(eint_t a);

extern ecdd_t
edd_acosh_d(efloat_t a);

extern ecdd_t
edd_acosh_z(empz_t a);

extern ecdd_t
edd_acosh_q(empq_t a);

#define edd_acosh_dd(a)			cacosh(a)

extern ecdd_t
edd_acosh_qq(ecqq_t a);

extern void
ecc_acosh_i(empc_t c, eint_t a);

extern void
ecc_acosh_d(empc_t c, efloat_t a);

extern void
ecc_acosh_z(empc_t c, empz_t a);

extern void
ecc_acosh_q(empc_t c, empq_t a);

extern void
ecc_acosh_r(empc_t c, empr_t a);

extern void
ecc_acosh_qq(empc_t c, ecqq_t a);

#define ecc_acosh_cc(c, a)		mpc_acosh(c, a, thr_rndc)

#define ed_atanh_i(a)			atanh(a)

#define ed_atanh_d(a)			atanh(a)

#define ed_atanh_z(a)			atanh(mpz_get_d(a))

#define ed_atanh_q(a)			atanh(mpq_get_d(a))

extern void
er_atanh_i(empr_t r, eint_t a);

extern void
er_atanh_z(empr_t r, empz_t a);

extern void
er_atanh_q(empr_t r, empq_t a);

#define er_atanh_r(r, a)		mpfr_atanh(r, a, thr_rnd)

extern ecdd_t
edd_atanh_i(eint_t a);

extern ecdd_t
edd_atanh_d(efloat_t a);

extern ecdd_t
edd_atanh_z(empz_t a);

extern ecdd_t
edd_atanh_q(empq_t a);

#define edd_atanh_dd(a)			catanh(a)

extern ecdd_t
edd_atanh_qq(ecqq_t a);

extern void
ecc_atanh_i(empc_t c, eint_t a);

extern void
ecc_atanh_d(empc_t c, efloat_t a);

extern void
ecc_atanh_z(empc_t c, empz_t a);

extern void
ecc_atanh_q(empc_t c, empq_t a);

extern void
ecc_atanh_r(empc_t c, empr_t a);

extern void
ecc_atanh_qq(empc_t c, ecqq_t a);

#define ecc_atanh_cc(c, a)		mpc_atanh(c, a, thr_rndc)

#define ed_exp_i(a)			exp(a)

#define ed_exp_d(a)			exp(a)

#define ed_exp_z(a)			exp(mpz_get_d(a))

#define ed_exp_q(a)			exp(mpq_get_d(a))

extern void
er_exp_i(empr_t r, eint_t a);

extern void
er_exp_z(empr_t r, empz_t a);

extern void
er_exp_q(empr_t r, empq_t a);

#define er_exp_r(r, a)			mpfr_exp(r, a, thr_rnd)

#define edd_exp_dd(a)			cexp(a)

extern ecdd_t
edd_exp_qq(ecqq_t a);

extern void
ecc_exp_qq(empc_t c, ecqq_t a);

#define ecc_exp_cc(c, a)		mpc_exp(c, a, thr_rndc)

#define ei_proj_i(a)			(a)

extern efloat_t
ed_proj_d(efloat_t a);

#define ez_proj_z(a)			(a)

#define eq_proj_q(a)			(a)

extern void
er_proj_r(empr_t r, empr_t a);

#define edd_proj_dd(a)			cproj(a)

#define eqq_proj_qq(a)			(a)

#define ecc_proj_cc(c, a)		mpc_proj(c, a, thr_rndc)

#define ed_log_i(a)			log(a)

#define ed_log_d(a)			log(a)

#define ed_log_z(a)			log(mpz_get_d(a))

#define ed_log_q(a)			log(mpq_get_d(a))

extern void
er_log_i(empr_t r, eint_t a);

extern void
er_log_z(empr_t r, empz_t a);

extern void
er_log_q(empr_t r, empq_t a);

#define er_log_r(r, a)			mpfr_log(r, a, thr_rnd)

extern ecdd_t
edd_log_i(eint_t a);

extern ecdd_t
edd_log_d(efloat_t a);

extern ecdd_t
edd_log_z(empz_t a);

extern ecdd_t
edd_log_q(empq_t a);

#define edd_log_dd(a)			clog(a)

extern ecdd_t
edd_log_qq(ecqq_t a);

extern void
ecc_log_i(empc_t c, eint_t a);

extern void
ecc_log_z(empc_t c, empz_t a);

extern void
ecc_log_q(empc_t c, empq_t a);

extern void
ecc_log_r(empc_t c, empr_t a);

extern void
ecc_log_qq(empc_t c, ecqq_t a);

#define ecc_log_cc(c, a)		mpc_log(c, a, thr_rndc)

#define ed_log2_i(a)			log2(a)

#define ed_log2_d(a)			log2(a)

#define ed_log2_z(a)			log2(mpz_get_d(a))

#define ed_log2_q(a)			log2(mpq_get_d(a))

extern void
er_log2_i(empr_t r, eint_t a);

extern void
er_log2_z(empr_t r, empz_t a);

extern void
er_log2_q(empr_t r, empq_t a);

#define er_log2_r(r, a)			mpfr_log2(r, a, thr_rnd)

extern ecdd_t
edd_log2_i(eint_t a);

extern ecdd_t
edd_log2_d(efloat_t a);

extern ecdd_t
edd_log2_z(empz_t a);

extern ecdd_t
edd_log2_q(empq_t a);

#define edd_log2_dd(a)			clog2(a)

extern ecdd_t
edd_log2_qq(ecqq_t a);

extern void
ecc_log2_i(empc_t c, eint_t a);

extern void
ecc_log2_z(empc_t c, empz_t a);

extern void
ecc_log2_q(empc_t c, empq_t a);

extern void
ecc_log2_r(empc_t c, empr_t a);

extern void
ecc_log2_qq(empc_t c, ecqq_t a);

extern void
ecc_log2_cc(empc_t c, empc_t a);

#define ed_log10_i(a)			log10(a)

#define ed_log10_d(a)			log10(a)

#define ed_log10_z(a)			log10(mpz_get_d(a))

#define ed_log10_q(a)			log10(mpq_get_d(a))

extern void
er_log10_i(empr_t r, eint_t a);

extern void
er_log10_z(empr_t r, empz_t a);

extern void
er_log10_q(empr_t r, empq_t a);

#define er_log10_r(r, a)			mpfr_log10(r, a, thr_rnd)

extern ecdd_t
edd_log10_i(eint_t a);

extern ecdd_t
edd_log10_d(efloat_t a);

extern ecdd_t
edd_log10_z(empz_t a);

extern ecdd_t
edd_log10_q(empq_t a);

#define edd_log10_dd(a)			clog10(a)

extern ecdd_t
edd_log10_qq(ecqq_t a);

extern void
ecc_log10_i(empc_t c, eint_t a);

extern void
ecc_log10_z(empc_t c, empz_t a);

extern void
ecc_log10_q(empc_t c, empq_t a);

extern void
ecc_log10_r(empc_t c, empr_t a);

extern void
ecc_log10_qq(empc_t c, ecqq_t a);

extern void
ecc_log10_cc(empc_t c, empc_t a);

#endif /* _emath_h */
